package com.sky.observer;

import java.util.ArrayList;
import java.util.List;

/**
 * @author : wushikai
 * <p>
 * date : 2020-08-18
 */

/*---------观察者模式实例---------------
 *
 * 一个对象设置一个数, 底下的订阅者立马转换这个数
 *
 * */

/**
 * 抽象订阅者
 */
public abstract class NumberFormatObserver {

    //订阅者的主题
    protected NumberSubject subject;

    //订阅者的方法
    public abstract void update();

}

/**
 * 数字主题类
 */
class NumberSubject {

    /*订阅/观察者*/
    List<NumberFormatObserver> subscribers = new ArrayList<>();

    int number; //将要改变进制的数字



    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
        notifySubscribers();
    }

    /**
     * 添加订阅者
     */
    public void attach(NumberFormatObserver subscriber) {
        subscribers.add(subscriber);
    }

    /**
     * 通知全部订阅者, 去接收订阅消息
     */
    public void notifySubscribers() {

        for (NumberFormatObserver subscriber : subscribers) {

            subscriber.update();
        }
    }

}

/**
 * 实际订阅者, 二进制处理订阅者
 */
class BinaryObserver extends NumberFormatObserver {


    public BinaryObserver(NumberSubject subject) {
        //同样的主题
        super.subject = subject;
        //把自己放入主题的订阅者中
        super.subject.attach(this);

    }

    @Override
    public void update() {
        System.out.println("Binary String: "
                + Integer.toBinaryString(subject.getNumber()));
    }
}


/**
 * 实际订阅者, 老八进制处理订阅者
 */
class OctalObserver extends NumberFormatObserver {


    public OctalObserver(NumberSubject subject) {
        //同样的主题
        super.subject = subject;
        //把自己放入主题的订阅者中
        super.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println( "Octal String: "
                + Integer.toOctalString( subject.getNumber() ) );
    }
}


/**
 * 实际订阅者, 十六进制处理订阅者
 */
class HexObserver extends NumberFormatObserver{

    public HexObserver(NumberSubject subject) {
        //同样的主题
        super.subject = subject;
        //把自己放入主题的订阅者中
        super.subject.attach(this);

    }

    @Override
    public void update() {
        System.out.println( "Hex String: "
                + Integer.toHexString( subject.getNumber() ).toUpperCase() );
    }
}


class calculator{


    public static void main(String[] args){

        NumberSubject subject = new NumberSubject();
        new HexObserver(subject);
        new OctalObserver(subject);
        new BinaryObserver(subject);
        subject.setNumber(10);

    }
}
